package cn.tedu.yitu.password.service;

import cn.hutool.core.util.StrUtil;
import cn.tedu.yitu.common.exception.ServiceException;
import cn.tedu.yitu.common.utils.JwtUtils;
import cn.tedu.yitu.common.web.ServiceCodeEnum;
import cn.tedu.yitu.password.dao.repository.UserCacheRepository;
import cn.tedu.yitu.protocol.bo.UserRegBO;
import cn.tedu.yitu.protocol.param.UserLoginInfoParam;
import cn.tedu.yitu.protocol.param.UserPhoneVerParam;
import cn.tedu.yitu.protocol.param.UserRegInfoParam;
import cn.tedu.yitu.protocol.dos.UserStateDO;
import cn.tedu.yitu.protocol.vo.UserLoginResultVO;
import cn.tedu.yitu.protocol.vo.UserRegResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserService {
    @Autowired
    private UserCacheRepository userCacheRepository;

    @Autowired
    private RedisTemplate redisTemplate;

    private String secretKey = "fNesMDkqrJFdsfDSwAbFLJ8SnsHJ438AF72D73aKJSmfdsafdLKKAFKDSJ";

    public void phoneVerification(UserPhoneVerParam userPhoneVerParam) {
        log.debug("开始处理【用户手机号验证】的业务，参数：{}", userPhoneVerParam);
        UserRegResultVO userRegResultVO = userCacheRepository.selectByPhoneNum(userPhoneVerParam.getPhoneNum());
        if(userRegResultVO!=null){
            throw new ServiceException(ServiceCodeEnum.USERNAME_ALREADY_EXISTS);
        }
        checkCaptcha(userPhoneVerParam);
    }

    private void checkCaptcha(UserPhoneVerParam userPhoneVerParam) {
        log.debug("开始处理【图形验证码验证】的业务，参数：{}", userPhoneVerParam);
        String captcha = userPhoneVerParam.getGraphValidateCode();
        log.debug("获取图形验证码，参数：{}", captcha);
        if(StrUtil.isEmptyIfStr(captcha)){
            throw new ServiceException("验证码不能为空");
        }
        String captchaKey = "captcha:" + userPhoneVerParam.getGraphValidateCode();
        Object value = redisTemplate.opsForValue().get(captchaKey);
        redisTemplate.delete(captchaKey);
        if(value == null){
            throw new ServiceException("验证码已过期");
        }
        if(!captcha.equalsIgnoreCase(value.toString())){
            throw new ServiceException("验证码错误");
        }
    }

    public void reg(UserRegInfoParam userRegInfoParam) {
        log.debug("开始处理【用户注册】的业务，参数：{}", userRegInfoParam);
        UserRegBO userRegBO = new UserRegBO();
        BeanUtils.copyProperties(userRegInfoParam,userRegBO);
        log.debug("Param2BO，入参：{}，出参：{}", userRegInfoParam,userRegBO);
        userRegBO.setCreateTime(new Date());
        userRegBO.setUpdateTime(new Date());
        userCacheRepository.insertUser(userRegBO);
    }

    public UserLoginResultVO login(UserLoginInfoParam userLoginInfoParam) {
        log.debug("开始处理【用户登录】的业务，参数：{}", userLoginInfoParam);
        //验证用户名及密码
        String phoneNum = userLoginInfoParam.getPhoneNum();
        String password = userLoginInfoParam.getPassword();
        //判断用户状态
        //取出用户ID
        Long userId = 1L;
        /*此处可以加入 记录用户登录日志 登录次数 */
        //生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", userId);
        claims.put("phoneNum", phoneNum);
        //map里面可以什么都可以放，但是放的多会token变长，每次访问别的系统都要带着，浪费网络带宽和存储空间
        //数据越多，加解密都变慢
        String jwt = JwtUtils.generate(claims, secretKey);
        log.debug("生成用户的JWT数据：{}", jwt);
        //获取权限信息 存入到redis里
        UserStateDO userStateDO = new UserStateDO();
        userStateDO.setUserId(userId);
        userStateDO.setEnable(1);
        String auth  = userCacheRepository.getAuth(userId);
        //"[{authority:'/article/add'},{authority:'/article/detail'}]";
        userStateDO.setAuth(auth); //从数据库5表查出的权限列表
        userCacheRepository.saveUserState(userStateDO);
        //定义登录返回数据
        UserLoginResultVO userLoginResultVO = new UserLoginResultVO();
        //继续设置token
        userLoginResultVO.setToken(jwt);
        userLoginResultVO.setUsername(phoneNum);
        userLoginResultVO.setId(userId);
        return userLoginResultVO;
    }
}
